home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
edit
/
jwpsrc.zip
/
FONT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-31
|
15KB
|
556 lines
/* Copyright (C) Stephen Chung, 1991-1993. All rights reserved. */
#include "jwp.h"
#include <math.h>
typedef struct fontcache {
KANJIFONT *font;
int width, height;
int size, bmsize;
int far *indexes;
BYTE far *bitmaps;
long int requests, hits, usage;
struct fontcache far *next, far *prev;
} FONTCACHE;
static FONTCACHE far *FontCaches; /* Base font always the first */
static BYTE far *BaseKana = NULL;
static int BaseKanaSize;
static long int BaseRequests = 0L, BaseHits = 0L;
static BOOL CacheEnabled = TRUE;
static BYTE far *CharBitmap = NULL;
#define DEFAULTLEADING (1.0 / 8.0)
#define DEFAULTSPACING (1.0 / 8.0)
#define KANASTART 0x2421
#define KANALENGTH 83
#define SYSCACHELEN 300
#define OTHERCACHELEN 100
static int AdjustBitmapWidth(int bytes)
{
int bmwidth;
if (bytes % sizeof(int)) {
bmwidth = (bytes / sizeof(int)) + 1;
bmwidth *= sizeof(int);
} else {
bmwidth = bytes;
}
return (bmwidth);
}
int AllignKanjiBitmap (BYTE far *buffer, BYTE far *source, int bytes, int lines)
{
int i, j, m, n;
int bmwidth;
bytes /= lines;
bmwidth = AdjustBitmapWidth(bytes);
if (bmwidth == bytes) {
_fmemcpy(buffer, source, bytes * lines);
} else {
for (j = 0; j < lines; j++) {
m = j * bytes;
n = j * bmwidth;
for (i = 0; i < bmwidth; i++)
buffer[n + i] = (i >= bytes) ? 0 : source[m + i];
}
}
return (bmwidth * lines);
}
int OpenFont(char *fname, KANJIFONT *f)
{
int fd;
FONTHEADER fh;
for (;;) {
fd = OpenFile(fname, &(f->of), OF_READ);
if (fd >= 0) break;
if (!RetryMessage ("Cannot open font file '%s'!", fname)) return (-1);
}
lseek(fd, 0L, 0);
read(fd, &fh, sizeof(FONTHEADER));
f->facename = (KANJI *) MemAlloc(NAMELEN);
kanjicpy(f->facename, fh.facename);
f->filename = (char *) MemAlloc(strlen(fname) + 5);
strcpy(f->filename, fname);
f->width = fh.width;
f->height = fh.height;
f->bmsize = fh.charsize;
f->offset = fh.offset;
f->verticals = fh.verticals;
f->holes = fh.holes;
f->leading = (fh.leading <= 0) ? (double) f->width * DEFAULTLEADING : fh.leading;
f->spacing = (fh.spacing <= 0) ? (double) f->height * DEFAULTSPACING : fh.spacing;
return (fd);
}
void EnableFontCache (BOOL On)
{
CacheEnabled = On;
if (On) {
if (CharBitmap != NULL) FreeBlock(CharBitmap);
CharBitmap = NULL;
}
}
static FONTCACHE far *CreateCache (KANJIFONT *font, int size, int bmsize)
{
int i;
long int block;
FONTCACHE far *f;
if (FontCaches == NULL) {
FontCaches = f = StructAlloc(FONTCACHE);
f->prev = f->next = NULL;
} else {
for (f = FontCaches; f->next != NULL; f = f->next);
f->next = StructAlloc(FONTCACHE);
f->next->prev = f;
f = f->next;
f->next = NULL;
}
if (f == NULL) return (NULL);
block = (long int) size * sizeof(int);
if (block > C64K) { size = C64K / bmsize; block = (long int) size * sizeof(int); }
f->indexes = (int far *) BlockAlloc(block);
block = (long int) size * (long int) bmsize;
if (block > C64K) { size = C64K / bmsize; block = (long int) size * (long int) bmsize; }
f->bitmaps = (BYTE far *) BlockAlloc(block);
f->font = font;
f->width = font->width;
f->height = font->height;
f->size = size;
f->bmsize = bmsize;
f->requests = f->hits = f->usage = 0L;
for (i = 0; i < size; i++) f->indexes[i] = -1;
return (f);
}
HFONT SelectAsciiFont (HDC hdc, char *facename, double ps, TEXTMETRIC *tmout)
{
int size;
HFONT hfont, oldfont;
TEXTMETRIC tm;
char buffer[MAXLINELEN];
size = (int) floor(ps * global.resolution.y / 72.0 + 0.5);
hfont = CreateFont(-size, 0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, PROOF_QUALITY, FF_DONTCARE, facename);
oldfont = SelectObject(hdc, hfont);
GetTextMetrics(hdc, &tm);
GetTextFace(hdc, MAXLINELEN, buffer);
if (stricmp(buffer, facename)) {
ErrorMessage(global.hwnd, "The font '%s' is not available in this size. The font "
"'%s' will be used instead.", facename, buffer);
}
SelectObject(hdc, oldfont);
if (tmout != NULL) *tmout = tm;
return (hfont);
}
HFONT FindMatchingScreenFont (HFONT hfont, double scale, TEXTMETRIC *tmout)
{
int size;
HDC hdc;
TEXTMETRIC tm;
HFONT screenfont;
char buffer[MAXLINELEN];
hdc = GetPrinterDC(TRUE, NULL);
if (hdc == NULL) hdc = CreateIC("DISPLAY", NULL, NULL, NULL);
SelectObject(hdc, hfont);
GetTextMetrics(hdc, &tm);
GetTextFace(hdc, MAXLINELEN, buffer);
DeleteDC(hdc);
hdc = CreateIC("DISPLAY", NULL, NULL, NULL);
size = (int) floor((double) (tm.tmHeight - tm.tmInternalLeading) * scale + 0.5);
screenfont = CreateFont(-size, 0, 0, 0, tm.tmWeight,
tm.tmItalic, tm.tmUnderlined, tm.tmStruckOut,
tm.tmCharSet, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, DRAFT_QUALITY,
tm.tmPitchAndFamily, buffer);
SelectObject(hdc, screenfont);
if (tmout != NULL) GetTextMetrics(hdc, tmout);
GetTextFace(hdc, MAXLINELEN, buffer);
DeleteDC(hdc);
return (screenfont);
}
int InitFonts(void)
{
int i, fd;
long int size, kanastart;
HFONT hfont;
BYTE charbuf[BUFSIZE];
/* The system font should have been opened already */
fd = OpenFile(NULL, &(SYSFONT->of), OF_READ | OF_REOPEN);
if (fd < 0) {
ErrorMessage(global.hwnd, "Funny! System font not opened yet!\n\n"
"Program will die now.");
exit(-1);
}
/* Get the adjusted size of a bitmap */
BaseKanaSize = AdjustBitmapWidth(SYSFONT->bmsize / SYSFONT->height) * SYSFONT->height;
/* Create the system kana cache */
size = (long int) KANALENGTH * BaseKanaSize;
if (size < C64K) {
/* Allocate the kanagana font cache */
/* #210 for 169 */
BaseKana = (BYTE far *) BlockAlloc(size);
kanastart = Jis2Index(KANASTART, SYSFONT->holes);
for (i = 0; i < KANALENGTH; i++, kanastart++) {
lseek(fd, kanastart * (long int) SYSFONT->bmsize + SYSFONT->offset, 0);
read(fd, charbuf, SYSFONT->bmsize);
AllignKanjiBitmap (&(BaseKana[i * BaseKanaSize]), charbuf, SYSFONT->bmsize, SYSFONT->height);
}
}
close(fd);
BaseRequests = BaseHits = 0L;
/* Allocate the system font cache */
FontCaches = NULL;
size = (long int) SYSCACHELEN * BaseKanaSize;
if (size > C64K) size = C64K / BaseKanaSize;
else size = SYSCACHELEN;
FontCaches = CreateCache (SYSFONT, size, BaseKanaSize);
hfont = CreateFont((int) -floor(DefAsciiFont.size * global.resolution.y / 72.0 + 0.5),
0, 0, 0, FW_NORMAL, 0, 0, 0, ANSI_CHARSET, OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS, PROOF_QUALITY, FF_DONTCARE, DefAsciiFont.facename);
DefAsciiFont.hfont =
FindMatchingScreenFont(hfont, global.dispscale / global.printscale,
&(DefAsciiFont.textmetric));
DeleteObject(hfont);
FontCharWidth(0, -2); /* Load the width tables */
return (1);
}
static int FontHash (int index, int bins)
{
return (index % bins);
}
BOOL IsSmallKana(KANJI jiscode)
{
BYTE hi, lo;
hi = HIBYTE(jiscode) & 0x7f;
lo = LOBYTE(jiscode) & 0x7f;
if (hi == 0x24 || hi == 0x25) { /* Hiragana & Katakana */
switch (lo) {
case 0x21: /* a */
case 0x23: /* i */
case 0x25: /* u */
case 0x27: /* e */
case 0x29: /* o */
case 0x63: /* ya */
case 0x65: /* yu */
case 0x67: /* yo */
case 0x43: /* tu */